<template>
  <div class="upload-card" v-viewer>
    <el-upload
      ref="uploadRef"
      v-bind="defaultAttr"
      v-if="props.mode !== 'detail' && filesList.length < (props.config?.limit || 5)"
      :file-list="filesList"
      action="/api-parking/system/oss/upload"
      :on-change="handleChange"
      :show-file-list="false"
      :before-upload="handleBeforeUpload"
      :on-success="handleSuccess"
      :headers="headers"
    >
      <div class="upload-btn">
        <el-icon><Plus /></el-icon>
      </div>
    </el-upload>
    <div class="upload-item" v-for="(item, index) in filesList" :key="item.ossId || index">
      <img :src="item?.url || parsingImage(item.raw)" alt="" />
      <el-icon v-show="props.mode !== 'detail'" @click.stop="handleRemove(index)"><CircleCloseFilled /></el-icon>
    </div>
  </div>
</template>

<script setup>
import { computed, watch } from 'vue'
import useUpload from '@/hooks/useUpload'
import { ElMessage } from 'element-plus'
import Cookies from 'js-cookie'
const { uploadFile, deleteFile } = useUpload()
const props = defineProps({
  modelValue: {
    type: Array,
  },
  config: {
    type: Object,
    default: () => {},
  },
  mode: {
    // 'edit' | 'detail' | 'add'
    type: String,
    default: 'detail',
  },
})
const headers = computed(() => {
  // 设置请求头
  return { Authorization: Cookies.get(process.env.envConfig.TOKEN) }
})

// v-model
const emits = defineEmits(['update:modelValue', 'change'])
const uploadRef = ref()
const defaultAttr = computed(() => {
  // 设置默认绑定值
  let { attrs = {} } = props.config
  // 判断禁用
  attrs['disabled'] = props.config?.disabled || false
  // 数量
  attrs['limit'] = props.config?.limit || 3
  // 数量
  attrs['size'] = props.config?.size || null
  // 尺寸
  attrs['width'] = props.config?.width || null
  attrs['height'] = props.config?.height || null
  // 文件类型
  attrs['accept'] = props.config?.accept || 'image/*'
  return { ...attrs }
})

// 文件
const filesList = ref(props?.modelValue || [])
watch(
  () => props?.modelValue,
  (newVal) => {
    filesList.value = newVal || []
  },
  { immediate: true, deep: true }
)

const handleChange = (file, files) => {
  filesList.value = files
  // 强制更新
  filesList.value = filesList.value.slice()
  emits('update:modelValue', files)
}
const handleRemove = (index) => {
  filesList.value.splice(index, 1)
}
const parsingImage = (file) => {
  if (file && file.type.startsWith('image/')) {
    // 生成图片 URL
    return URL.createObjectURL(file)
  } else {
    return ''
  }
}
const handleBeforeUpload = (file) => {
  return new Promise((resolve, reject) => {
    if (defaultAttr.value.width || defaultAttr.value.height) {
      // 检查图片尺寸
      const img = new Image()
      img.onload = () => {
        if (defaultAttr.value.width && !defaultAttr.value.height && img.width > defaultAttr.value.width) {
          ElMessage.error(`图片宽度必须小于 ${defaultAttr.value.width}`)
          filesList.value.splice(filesList.value.length - 1, 1)
          reject(new Error('Invalid image dimensions'))
        } else if (!defaultAttr.value.width && defaultAttr.value.height && img.height > defaultAttr.value.height) {
          ElMessage.error(`图片高度必须小于 ${defaultAttr.value.height}`)
          filesList.value.splice(filesList.value.length - 1, 1)
          reject(new Error('Invalid image dimensions'))
        } else if (
          defaultAttr.value.width &&
          defaultAttr.value.height &&
          (img.width > defaultAttr.value.width || img.height > defaultAttr.value.height)
        ) {
          ElMessage.error(`图片尺寸必须小于 ${defaultAttr.value.width}*${defaultAttr.value.height}`)
          filesList.value.splice(filesList.value.length - 1, 1)
          reject(new Error('Invalid image dimensions'))
        } else {
          resolve(true)
        }
      }
      img.src = URL.createObjectURL(file)
    } else {
      resolve(true)
    }
  })
}
const handleSuccess = (res) => {
  if (res.code === 200) {
    filesList.value[filesList.value.length - 1] = res?.data
  } else {
    ElMessage.error(res?.msg || '上传失败')
  }
}
</script>

<style lang="scss" scoped>
.upload-card {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.upload-btn {
  width: 30px;
  height: 30px;
  border-radius: 6px;
  cursor: pointer;
  border: 1px dashed var(--el-border-color-darker);
  text-align: center;
}
.upload-item {
  width: 30px;
  height: 30px;
  position: relative;
  img {
    width: 100%;
    height: 100%;
    border-radius: 6px;
  }
  .el-icon {
    position: absolute;
    font-size: 16px;
    right: -6px;
    top: -6px;
    color: var(--el-color-danger);
    display: none;
    cursor: pointer;
  }
  &:hover {
    .el-icon {
      display: block;
    }
  }
}
</style>
